let logger = require("pomelo-logger").getLogger(__filename);
let DateUtil = require("../../../utils/dateUtil");
let accountComponentCreator = require("./components/accountComponent").create;
let connectionComponentCreator = require("./components/connectionComponent").create;
let currencyComponentCreator = require("./components/currencyComponent").create;
let permissionComponentCreator = require("./components/permissionComponent").create;
let mailComponentCreator = require("./components/mailComponent").create;
let statComponentCreator = require("./components/statComponent").create;
let gameComponentCreator = require("./components/gameComponent").create;

let Player = function () {
    this.accountComponent = accountComponentCreator(this);
    this.connectionComponent = connectionComponentCreator(this);
    this.currencyComponent = currencyComponentCreator(this);
    this.permissionComponent = permissionComponentCreator(this);
    this.mailComponent = mailComponentCreator(this);
    this.statComponent = statComponentCreator(this);
    this.gameComponent = gameComponentCreator(this);
};

Player.prototype.fromBSON = function (document) {
    this.accountComponent.fromBSON(document);
    this.currencyComponent.fromBSON(document);
    this.permissionComponent.fromBSON(document);
    this.mailComponent.fromBSON(document);
    this.statComponent.fromBSON(document);
    this.gameComponent.fromBSON(document);
};

Player.prototype.toBSON = function () {
    let document = {};
    this.accountComponent.buildBSON(document);
    this.currencyComponent.buildBSON(document);
    this.permissionComponent.buildBSON(document);
    this.mailComponent.buildBSON(document);
    this.statComponent.buildBSON(document);
    this.gameComponent.buildBSON(document);
    return document;
};

Player.prototype.toJSON = function () {
    return {
        account: this.accountComponent.toJSON(),
        currency : this.currencyComponent.toJSON(),
        permission : this.permissionComponent.toJSON(),
        game: this.gameComponent.toJSON()
    };
};

Player.prototype.pushEnterLobby = function () {
    this.pushMessage("onEnterLobby", {
        dummy: 1
    });
};

Player.prototype.pushInitializePlayer = function () {
    this.pushMessage("onInitializePlayer", {
        player: this.toJSON()
    });
};

Player.prototype.pushInitializeGames = function (games) {
    this.pushMessage("onInitializeGames", {
        games: games
    });
};

Player.prototype.pushInitializeSwiper = function (swiperItems) {
    this.pushMessage("pushInitializeSwiper", {
        swiperItems: swiperItems
    });
};

Player.prototype.pushInitializeActivity = function (activities) {
    this.pushMessage("pushInitializeActivity", {
        activities: activities
    });
};

Player.prototype.pushInitializeAnnouncement = function (announcements) {
    this.pushMessage("pushInitializeAnnouncement", {
        announcements: announcements
    });
};

Player.prototype.pushUpdateSelfAccount = function () {
    this.pushMessage("onUpdateSelfAccount", {
        account: this.accountComponent.toJSON()
    });
};

Player.prototype.isTokenExpired = function () {
    return this.accountComponent.isTokenExpired();
};

Player.prototype.pushUpdateSelfCurrency = function () {
    return this.pushMessage("onUpdateSelfCurrency", {
        currency: this.currencyComponent.toJSON()
    });
};

Player.prototype.pushSetAllMails = function () {
    this.pushMessage("onSetAllMails", {mails : this.mailComponent.toJSON()});
};

Player.prototype.pushUpdateMails = function (mailIds) {
    let result = [];
    for (let mailId of mailIds) {
        let mail = this.mailComponent.findById(mailId);
        if (!!mail) {
            result.push(mail.toJSON());
        }
    }
    this.pushMessage("onUpdateMails", {
        mails: result
    });
};

Player.prototype.pushDeleteMails = function (mailIds) {
    this.pushMessage("onDeleteMails", {
        mailIds: mailIds
    });
};

Player.prototype.pushSetBusinessConfig = function (businessConfig) {
    this.pushMessage("onSetBusinessConfig", {
        shareAward: businessConfig.shareAward || 10,
        shareTimes: businessConfig.shareTimes || 0
    });
};

Player.prototype.pushSetConfig = function (configs) {
    this.pushMessage("onSetConfig", {
        configs : configs
    });
};

Player.prototype.update = function (now) {

};

Player.prototype.login = function () {
    logger.info("player uid=" + this.accountComponent.getUid() + " login");
    this.accountComponent.login();
    this.mailComponent.login();
    if (!DateUtil.isSameDay(this.getLastLoginTime(), DateUtil.nowMS())) {
        logger.info("changeDailyRecharge to 0 @ :" + DateUtil.nowMS());
        this.changeDailyRecharge(0);
    }
    this.changeLastLoginTime(DateUtil.nowMS());
};

Player.prototype.logout = function () {
    logger.info("player uid=" + this.accountComponent.getUid() + " logout");
    this.accountComponent.logout();
};

Player.prototype.readMail = function (id) {
    logger.info("player " + this.getUid()+ " read mail id=" + id);
    let result = this.mailComponent.readMail(id);
    this.pushUpdateSelfCurrency();
    return result;
};

Player.prototype.readAllMails = function () {
    logger.info("player " + this.getUid() + " read all mail ");
    let result = this.mailComponent.readAllMails();
    this.pushUpdateSelfCurrency();
    return result;
};

Player.prototype.deleteMail = function (id) {
    logger.info("player " + this.getUid()+ " delete mail id=" + id);
    return this.mailComponent.deleteMail(id);
};

Player.prototype.containMail = function (id) {
    return this.mailComponent.contain(id);
};

Player.prototype.sendMail = function (mailData) {
    return this.mailComponent.sendMail(mailData);
};

Player.prototype.getToken = function () {
    return this.accountComponent.getToken();
};

Player.prototype.getRefreshTokenTime = function () {
    return this.accountComponent.getRefreshTokenTime();
};

Player.prototype.getUid = function () {
    return this.accountComponent.getUid();
};

Player.prototype.getChannelUid = function () {
    return this.accountComponent.getChannelUid();
};

Player.prototype.getUserChannel = function () {
    return this.accountComponent.getUserChannel();
};

Player.prototype.setDBId = function (dbId) {
    this.accountComponent.setDBId(dbId);
};

Player.prototype.setDescription = function (description) {
    this.accountComponent.setDescription(description);
};

Player.prototype.getDescription = function () {
    return this.accountComponent.getDescription();
};

Player.prototype.setConnectionId = function (session) {
    this.connectionComponent.setConnectionId(session);
};

Player.prototype.getConnectionId = function () {
    return this.connectionComponent.getConnectionId();
};

Player.prototype.getFrontendId = function () {
    return this.connectionComponent.getFrontendId();
};

Player.prototype.getSessionId = function () {
    return this.connectionComponent.getSessionId();
};

Player.prototype.touchToken = function () {
    this.accountComponent.touchToken();
};

Player.prototype.updateWechatTokenTo = function (token) {
    this.accountComponent.updateWechatTokenTo(token);
};

Player.prototype.isEnabled = function () {
    return this.permissionComponent.isEnabled();
};

Player.prototype.getDisableReason = function () {
    return this.permissionComponent.getDisableReason();
};

Player.prototype.disable = function (reason) {
    return this.permissionComponent.disable(reason);
};

Player.prototype.enable = function () {
    return this.permissionComponent.enable();
};

Player.prototype.isOnline = function () {
    return this.connectionComponent.isOnline();
};

Player.prototype.kick = function () {
    return this.connectionComponent.kick();
};

Player.prototype.pushMessage = function (route, message) {
    this.connectionComponent.pushMessage(route, message);
};

Player.prototype.getNickname = function () {
    return this.accountComponent.getNickname();
};

Player.prototype.getGender = function () {
    return this.accountComponent.getGender();
};

Player.prototype.getAvatar = function () {
    return this.accountComponent.getAvatar();
};

Player.prototype.getDiamond = function () {
    return this.currencyComponent.getDiamond();
};

Player.prototype.changeDiamond = function (diamond) {
    this.currencyComponent.changeDiamond(diamond);
};

Player.prototype.getGold = function () {
    return this.currencyComponent.getGold();
};

Player.prototype.changeGold = function (gold) {
    this.currencyComponent.changeGold(gold);
};

Player.prototype.getFangka = function () {
    return this.currencyComponent.getFangka();
};

Player.prototype.changeFangka = function (fangka) {
    this.currencyComponent.changeFangka(fangka);
};

Player.prototype.getDailyRecharge = function () {
    return this.currencyComponent.getDailyRecharge();
};

Player.prototype.changeDailyRecharge = function (recharge) {
    this.currencyComponent.changeDailyRecharge(recharge);
};

Player.prototype.getTotalRecharge = function () {
    return this.currencyComponent.getTotalRecharge();
};

Player.prototype.addTotalRecharge = function (recharge) {
    this.currencyComponent.addTotalRecharge(recharge);
};

Player.prototype.getLastLoginTime = function () {
    return this.currencyComponent.getLastLoginTime();
};

Player.prototype.changeLastLoginTime = function (lastRechargeTime) {
    this.currencyComponent.changeLastLoginTime(lastRechargeTime);
};

Player.prototype.getPlayTimes = function () {
    return this.statComponent.getPlayTimes();
};

Player.prototype.addPlayTimes = function () {
    this.statComponent.addPlayTimes();
};

Player.prototype.getSharedTime = function () {
    return this.statComponent.getSharedTime();
};

Player.prototype.canShareToday = function (ts, count) {
    let shareTimes = this.getSharedTime();
    for(let shareTime of shareTimes) {
        if(DateUtil.isSameDay(shareTime, ts)) {
            count = count - 1;
        }
    }
    return count > 0;
};

Player.prototype.addShareTime = function (ts) {
    return this.statComponent.addShareTime(ts);
};

Player.prototype.getPlayingGame = function () {
    return this.gameComponent.getGame();
};

Player.prototype.getPlayingGameId = function () {
    return this.gameComponent.getGameId();
}

Player.prototype.join = function(game) {
    this.gameComponent.join(game);
};

Player.prototype.leave = function () {
    this.gameComponent.leave();
};

function createNewGuestPlayer(uid) {
    let player = new Player();
    player.accountComponent.initGuest(uid);
    player.currencyComponent.diamond = 1000;
    return player;
}

function createNewWechatPlayer(uid, wechatObject) {
    let player = new Player();
    player.accountComponent.initWechat(uid, wechatObject);
    //TODO: init currency
    return player;
}

function createNewWywPlayer(uid, wywObject) {
    let player = new Player();
    player.accountComponent.initWyw(uid, wywObject);
    //TODO: init currency
    player.currencyComponent.initWyw(uid);
    return player;
}

function createPlayerFromBSON(document) {
    let player = new Player();
    player.fromBSON(document);
    return player;
}

module.exports.createFromBSON = createPlayerFromBSON;
module.exports.createNewGuestPlayer = createNewGuestPlayer;
module.exports.createNewWechatPlayer = createNewWechatPlayer;
module.exports.createNewWywPlayer = createNewWywPlayer;
